package com.example.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.example.common.Result;
import com.example.common.enums.RoleEnum;
import com.example.entity.Staff;
import com.example.exception.CustomException;
import com.example.service.StaffService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * 扫码信息接收接口控制器
 */
@RestController // 标记为接口类，返回 JSON 数据
@Slf4j // Lombok 注解，简化日志打印（无需手动创建 Logger 对象）
public class GetInfoController {

    @Autowired
    private StaffService staffService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 扫码触发的接口：接收并返回扫码设备信息
     * 请求方式：GET
     * 访问路径：/getInfo（配合 ngrok 后地址为：https://dated-nonparabolically-zackary.ngrok-free.dev/getInfo）
     */
    @Transactional
    @GetMapping("/getInfoRegister")
    public Result receiveScanInfo(@RequestParam("scene") String scene, HttpServletRequest request) {
        // 1. 从请求中提取关键信息
        String userAgent = request.getHeader("User-Agent"); // 设备/浏览器信息（如手机型号、浏览器类型）
        String clientIp = getRealIp(request); // 扫码设备的真实 IP（兼容 ngrok 穿透场景）
        String referer = request.getHeader("Referer"); // 跳转来源（部分扫码工具可能为空）
        String acceptLanguage = request.getHeader("Accept-Language"); // 语言偏好（如 zh-CN）
        String requestTime = String.valueOf(System.currentTimeMillis()); // 请求时间戳（方便记录）

        // 2. 打印日志（便于后端查看扫码记录）
        log.info("扫码请求信息：IP={}, 设备信息={}, 语言={}, 来源={}",
                clientIp, userAgent, acceptLanguage, referer);
        if (!userAgent.contains("WeChat")) {
            throw new CustomException("请使用微信扫码");
        }
        Staff staff = new Staff();
        staff.setUsername("wx_" + IdUtil.fastSimpleUUID().hashCode());
        staff.setPassword("123");
        staff.setWorkCode(ObjectUtil.defaultIfNull(staff.getWorkCode(), "STF" + IdUtil.getSnowflake().nextIdStr()));
        staff.setRole(ObjectUtil.defaultIfNull(staff.getRole(), RoleEnum.STAFF.name()));
        staffService.register(staff);
        staff.setPassword("123");
        Staff dbStaff = staffService.login( staff);
        String key = "scan:" + scene;
        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(dbStaff), Duration.ofMinutes(5));

//        // 3. 封装结果为 JSON，返回给扫码端（可选，也可仅后端记录不返回）
        Map<String, String> result = new HashMap<>();
        result.put("status", "success");
        result.put("message", "扫码信息已接收");
        result.put("scanTime", requestTime);
        result.put("clientIp", clientIp);
        result.put("deviceInfo", userAgent);

        return Result.success(result);
    }

    @GetMapping("/scanResult")
    public Result scanResult(String scene) {
        String key = "scan:" + scene;
        Staff staff = JSONUtil.toBean(stringRedisTemplate.opsForValue().get(key), Staff.class);
        if (staff == null) return Result.error("not ready");
        staff.setPassword(null);
        stringRedisTemplate.delete(key);          // 一次性取用
        if (staff.getUsername()!= null) {
            return Result.success(staff);
        }
        else
            return Result.error("not ready");
    }

    /**
     * 工具方法：获取扫码设备的真实 IP（解决 ngrok 穿透后 IP 显示为代理地址的问题）
     */
    private String getRealIp(HttpServletRequest request) {
        // 1. 先从 ngrok 或反向代理传递的头中获取真实 IP
        String ip = request.getHeader("X-Real-IP");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }
        // 2. 若仍未获取到，使用默认方法（适用于无代理的本地测试）
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 3. 处理多 IP 场景（X-Forwarded-For 可能返回多个 IP，取第一个）
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        return ip;
    }
}
